package com.chinacoal.hr.levelimpl.service.impl;

import com.baomidou.mybatisplus.plugins.Page;
import com.chinacoal.hr.levelapi.api.WorkflowClient;
import com.chinacoal.hr.levelapi.entity.*;
import com.chinacoal.hr.levelapi.util.Result;
import com.chinacoal.hr.levelimpl.dao.EmployeeDao;
import com.chinacoal.hr.levelimpl.param.EmployeeVO;
import com.chinacoal.hr.levelimpl.param.PositionVO;
import com.chinacoal.hr.levelimpl.service.OrganizationService;
import com.chinacoal.hr.levelimpl.service.WorkflowService;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author: YunTao.Li
 * @create: 2019-12-12 22:11
 * @description:
 **/
@Service
public class WorkflowServiceImpl implements WorkflowService {
    private final Logger logger = LoggerFactory.getLogger(WorkflowServiceImpl.class);

    public static final String PROCESSDEFNAME_TRAVEL = "com.primeton.eos.ccip_hr_attendance_travel";
    //    public static final String PROCESSDEFNAME_LEAVE = "ccip_hr_attendance_leave";
    public static final String PROCESSDEFNAME_LEAVE = "com.primeton.eos.ccip_hr_attendance_leave";


    public static final String PROCESSDEFNAME_APPEAL = "com.primeton.eos.ccip_hr_attendance_appeal";

    public static final String WORKITEM_OPCODE_AGREE = "1000";
    public static final String WORKITEM_OPCODE_DISAGREE = "1001";
    public static final String WORKITEM_OPCODE_DRAWBACK = "1002";


    @Autowired
    private WorkflowClient workflowClient;

    @Autowired
    private EmployeeDao employeeDao;

    @Autowired
    private OrganizationService organizationService;

    /**
     * 创建并启动流程且完成第一个节点
     *
     * @param processDefName : 流程定义名称
     * @return : java.lang.String
     * @author : YunTao.Li
     * @date : 2019/12/18 2019/12/18
     */
    public String createAndStartAndFinishFirstWorkitem(String processDefName, String processInstTitle, String insCode, String bizID, Object recordObject) throws Throwable {
        try {
            Map<String, Object> businessParam = this.businessParamConstructor(recordObject);

            SubmitParam param = new SubmitParam();
            param.setProcessCode(processDefName);// TODO:后面需要调用获得编码接口
            param.setIsSkip("Y");

            if (StringUtils.isNotBlank(processInstTitle)) {
                businessParam.put("taskTitle", processInstTitle);
                businessParam.put("businessId", bizID);
                businessParam.put("sysCode", "SYS-20200606-1000"); //门户协同平台ccms_utask_callback表的字段
            }

            // 根据不同的流程定义添加不同的业务编码
            if (WorkflowServiceImpl.PROCESSDEFNAME_LEAVE.equals(processDefName)) { // 请假单
                businessParam.put("bizCode", "ccms_hr_leave");
            } else if (WorkflowServiceImpl.PROCESSDEFNAME_TRAVEL.equals(processDefName)) { //因公外出申请单
                businessParam.put("bizCode", "ccms_hr_travel");
            } else if (WorkflowServiceImpl.PROCESSDEFNAME_APPEAL.equals(processDefName)) { //考勤申诉单
                businessParam.put("bizCode", "ccms_hr_appeal");
            }

            param.setBusinessParam(businessParam);

            if (StringUtils.isNotBlank(insCode)) {
                param.setInstanceId(Long.parseLong(insCode));
            }

            System.out.println("ready to load processSubmit:" + processDefName);
            //  调用一下 流程引擎里的 processSubmit  提交流程接口
            Result<InstanceEntity> instanceEntityResult = workflowClient.processSubmit(param);
            int code = instanceEntityResult.getCode();
            if (10000 != code) {
                throw new Exception("code:" + code + "-" + instanceEntityResult.getMsg());
            }

            logger.info("call the ，processSubmit result code:" + instanceEntityResult.getCode() + " msg:" + instanceEntityResult.getMsg() + "data:" + instanceEntityResult.getData());

            InstanceEntity instanceEntity = instanceEntityResult.getData();
            logger.info(instanceEntity.toString());
            long processDefID = instanceEntity.getProcessId();
            long processInstID = instanceEntity.getInstanceId();
            String currentState = instanceEntity.getCurrentState();

            System.out.println("submit success : processDefID:" + processDefID
                    + " processDefName:" + processDefName
                    + " processInstID : " + processInstID + " currentState:" + currentState);

            return String.valueOf(processInstID);
        } catch (Throwable e) {
            e.printStackTrace();
            throw e;
        }
    }

    /**
     * 完成工作项
     *
     * @param processInstID :
     * @return : void
     * @author : YunTao.Li
     * @date : 2019/12/18 2019/12/18
     */
    public void finishWorkitem(long processInstID, long taskId, String approvalContext, String opcode) throws Throwable {
        try {
            ApproveParam param = new ApproveParam();
            param.setInstanceId(processInstID);
            param.setOpcode(opcode);
            param.setApprovalOpinion(approvalContext);
            if (taskId != 0) {
                param.setTaskId(taskId);
            }
            // 审批待办接口
            Result<InstanceEntity> instanceEntityResult = workflowClient.completeTask(param);
            int code = instanceEntityResult.getCode();
            System.out.println("get result of completeTask  code:" + instanceEntityResult.getCode() + " msg:" + instanceEntityResult.getMsg() + "data:" + instanceEntityResult.getData());
            if (10000 != code) {
//                throw new Exception("code:" + code + "-" + instanceEntityResult.getMsg());
            }
        } catch (Throwable e) {
            e.printStackTrace();
            throw e;
        }
    }

    @Override
    public List getApprovalHistorys(String processInstID) throws Throwable {
        try {
            Result<Page<ApprovalHistoryEntity>> pageResult = workflowClient.getApprovalHistory(0, 0, Long.parseLong(processInstID));

            int code = pageResult.getCode();
            String msg = pageResult.getMsg();
            List<ApprovalHistoryEntity> historyList = pageResult.getData().getRecords();

            System.out.println("get result of completeTask  code:" + code + " msg:" + msg + "data:" + historyList);
            if (10000 != code) {
                throw new Exception("code:" + code + "-" + msg);
            }

            System.out.println("开始循环历史记录");
            for (ApprovalHistoryEntity entity : historyList) {

                System.out.println(entity.toString());
            }
            return historyList;
        } catch (Throwable e) {
            e.printStackTrace();
            throw e;
        }
    }

    /**
     * 构造流程相关数据
     *
     * @param businessRecord :
     * @return : java.util.Map<java.lang.String,java.lang.Object>
     * @author : YunTao.Li
     * @date : 2020/8/6 2020/8/6
     */
    private Map<String, Object> businessParamConstructor(Object businessRecord) throws Throwable {
        String orgCode = null;
        String empCode = null;
        String days = null;
        String deptCode = null;

        try {
            orgCode = (String) businessRecord.getClass().getMethod("getOrgCode").invoke(businessRecord, null);
        } catch (Throwable e) {
            System.out.println("businessParamConstructor orgCode Throwable");
        }

        try {
            deptCode = (String) businessRecord.getClass().getMethod("getDeptCode").invoke(businessRecord, null);
        } catch (Throwable e) {
            System.out.println("businessParamConstructor deptCode Throwable");
        }

        try {
            empCode = (String) businessRecord.getClass().getMethod("getEmpCode").invoke(businessRecord, null);
        } catch (Throwable e) {
            System.out.println("businessParamConstructor orgCode Throwable");
        }

        try {
            double daysDouble = (Double) businessRecord.getClass().getMethod("getDays").invoke(businessRecord, null);
            days = new BigDecimal(daysDouble).toString();
        } catch (Throwable e) {
        }

        /**
         * 添加流程业务信息，包括天数，porgid，岗位信息等
         * */
        Map<String, Object> businessParam = new HashMap<>();
        Organization organization = organizationService.getOrganizationByCode(deptCode);
        String porgId = organization.getParentOrgId();

        // 当前人岗位
        List<PositionVO> positionVOList = employeeDao.employeeMapper.selectPositionInfoByEmpcode(empCode);
        for (int i = 0; i < positionVOList.size(); i++) {
            PositionVO positionVO = positionVOList.get(i);
            String posiCode = positionVO.getPosiCode();
            businessParam.put("emppos", posiCode); // 当前人岗位
        }

        // 当前人领导岗位
        String cz = "";
        String fjl = "";
        String jl = "";
        String jlfjl = "";
        String fg = "";
        String zy = "1713";

        List<EmployeeVO> employeeVOS = employeeDao.employeeMapper.selectEmpPositionsByEmpcode(empCode);
        for (int i = 0; i < employeeVOS.size(); i++) {
            EmployeeVO employeeVO = employeeVOS.get(i);
            String posiCode = employeeVO.getPosiCode();
            String empId = employeeVO.getEmpId();
            if (("cz").equals(posiCode)) {
                cz += empId + ",";
            } else if (("fjl").equals(posiCode)) {
                fjl += empId + ",";
                jlfjl += empId + ",";
            } else if (("fjl").equals(posiCode)) {
                fjl += empId + ",";
                jlfjl += empId + ",";
            } else if (("jl").equals(posiCode)) {
                jl += empId + ",";
                jlfjl += empId + ",";
            } else if (("fg").equals(posiCode)) {
                fg += empId + ",";
            } else if (("zy").equals(posiCode)) {
                zy += empId + ",";
            }
        }
        cz = cz.endsWith(",") ? cz.substring(0, cz.length() - 1) : cz;
        fjl = fjl.endsWith(",") ? fjl.substring(0, fjl.length() - 1) : fjl;
        jl = jl.endsWith(",") ? jl.substring(0, jl.length() - 1) : jl;
        jlfjl = jlfjl.endsWith(",") ? jlfjl.substring(0, jlfjl.length() - 1) : jlfjl;
        fg = fg.endsWith(",") ? fg.substring(0, fg.length() - 1) : fg;

        businessParam.put("cz", cz); // 处长
        businessParam.put("fjl", fjl); // 处长
        businessParam.put("jl", jl); // 处长
        businessParam.put("jlfjl", jlfjl); // 处长
        businessParam.put("fg", fg); // 处长
        businessParam.put("zy", zy); // 处长
        businessParam.put("day", days);
        businessParam.put("porgid", porgId);
        businessParam.put("hr", "1750");
        return businessParam;
    }
}
